package com.kusiri.kframework
{
	
	import com.kusiri.kframework.component.IKfComponent;
	import com.kusiri.kframework.component.KfComponentManager;
	import com.kusiri.kframework.plugin.KfPluginLoader;
	import com.kusiri.kframework.prana.ApplicationContext;
	import com.kusiri.kframework.ui.*;
	
	import flash.events.Event;
	
	import mx.collections.ArrayCollection;
	import mx.core.Application;
	import mx.core.Container;
	
	/**
	 * The main application class.
	 */
	public class KfContext
	{
		
		/**
		 * Prana id string constants
		 */
		public const PLUGIN_SET_ID : String = 'kf-plugin-set';


		/**
		 * Instance vars/functions
		 */
		
		public var kfApplication : IKfApplication;
		
		private var componentManager : KfComponentManager;
		
		/**
		 * What the UI container is contained by
		 */
		public var uiContainerParent:Container = Application.application as Container;
		
		/**
		 * The UI container
		 */
		public var container : IKfUiContainer;
		
		/**
		 * Prana object definition loader
		 */
		private var applicationContext:ApplicationContext;


		public function KfContext() : void
		{
			this.kfApplication = new KfApplicationLocator().kfApplication;
			componentManager = new KfComponentManager(this);
		}
		
		/**
		 * Called to kick off setting up the application
		 */
		public function initialize( config:*, callback:Function ) : void
		{
			
			// load a single 'applicationContext.xml' config
			applicationContext = new ApplicationContext(this, config);
			
			applicationContext.addEventListener(Event.COMPLETE, 
				function (event:Event) : void
				{
					onApplicationContextComplete(callback);
				});
			
			applicationContext.load();
		} 

		/**
		 * the object loader is complete
		 * we can now reference the container inside the loader and get
		 * objects from it
		 */
		private function onApplicationContextComplete(callback:Function):void 
		{
			
			// load plugins
			
			var plugins:ArrayCollection = applicationContext.getObject(PLUGIN_SET_ID) as ArrayCollection;
			
			new KfPluginLoader().load(plugins, callback);

		}
		
		/**
		 * Get an object from prana, initialising it for use
		 */
		public function getComponent(factoryOrInstanceId:String, onSuccess : Function, onFail : Function) : void
		{			
			var component : IKfComponent = getObject(factoryOrInstanceId) as IKfComponent;
			if (component == null) throw new Error("Can't find "+factoryOrInstanceId+" in context");
			initializeComponent(component, onSuccess, onFail);
		}
		
		public function initializeComponent(component : IKfComponent, onSuccess : Function, onFail : Function) : void
		{
			componentManager.initializeComponent(component, onSuccess, onFail);
		}

		
		/**
		 * Get an object from prana, initialising it for use
		 */
		public function getObject(factoryOrInstanceId:String) : Object
		{			
			return applicationContext.getObject(factoryOrInstanceId);
		}
		
		/**
		 * Called when we are waiting for something
		 */
		public function waitingForSomething() : void
		{
			kfApplication.waitingForSomething();
		}
		
		/**
		 * Called when we are waiting for something
		 */
		public function finishedWaitingForSomething() : void
		{
			kfApplication.finishedWaitingForSomething();
		}

	}
}